#include "Ros2RpcTransformerVisitor.h"
#include "Ast.h"
#include <string>

// Helper function to check suffix
bool Ros2RpcTransformerVisitor::hasSuffix(const std::string& str, const std::string& suffix) {
    if (str.length() < suffix.length()) return false;
    return str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0;
}

void Ros2RpcTransformerVisitor::visit(StructDefNode& node) {
    // Check if struct name ends with _Request or _Response
    if (!node.identifier_) return;
    const std::string& name = *node.identifier_;
    if (hasSuffix(name, "_Request") || hasSuffix(name, "_Response")) {
        // Prepare writer_guid_ member
        // writer_guid_ : unsigned char writer_guid_[16];
        // sequence_num_ : long long sequence_num_;
        // 1. Create type for writer_guid_ (array of 16 unsigned char)
        BaseTypeNode* ucharType = new BaseTypeNode(BaseTypeNode::Type::UCHAR);
        // Create array dimension node for [16]
        LiteralNode* size16Literal = new LiteralNode(16);
        PrimaryExprNode* size16Primary = new PrimaryExprNode(nullptr, size16Literal, nullptr);
        UnaryExprNode* size16Unary = new UnaryExprNode(UnaryExprNode::UnaryOp::NONE, size16Primary);
        MultExprNode* size16Mult = new MultExprNode(nullptr, size16Unary, MultExprNode::MultOp::NONE);
        AddExprNode* size16Add = new AddExprNode(nullptr, size16Mult, AddExprNode::AddOp::NONE);
        ShiftExprNode* size16Shift = new ShiftExprNode(nullptr, size16Add, ShiftExprNode::ShiftOp::NONE);
        AndExprNode* size16And = new AndExprNode(nullptr, size16Shift);
        XorExprNode* size16Xor = new XorExprNode(nullptr, size16And);
        OrExprNode* size16Or = new OrExprNode(nullptr, size16Xor);
        ConstExprNode* size16Const = size16Or;
        PositiveIntConstNode* size16 = size16Const;
        // You may want to set the value inside PositiveIntConstNode if needed
        ListNode<FixedArraySizeNode*>* dims16 = new ListNode<FixedArraySizeNode*>();
        dims16->add(new FixedArraySizeNode(size16));
        // Create member node for writer_guid_
        std::string* writerGuidName = new std::string("writer_guid_");
        MemberNode* writerGuidMember = new MemberNode(ucharType, writerGuidName, dims16, nullptr);

        // 2. Create type for sequence_num_ (long long)
        BaseTypeNode* longlongType = new BaseTypeNode(BaseTypeNode::Type::LONGLONG);
        std::string* seqNumName = new std::string("sequence_num_");
        MemberNode* seqNumMember = new MemberNode(longlongType, seqNumName, nullptr, nullptr);

        // 3. Insert at the front of members_
        if (node.members_) {
            node.members_->nodes_.insert(node.members_->nodes_.begin(), seqNumMember);
            node.members_->nodes_.insert(node.members_->nodes_.begin(), writerGuidMember);
        }
    }
    // Continue traversal if needed
    DefaultVisitor::visit(node);
}
